package com.demo.function.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.Date;

/**
 * http://www.hollischuang.com/archives/110
 * jvm jstack 命令
 */
@Slf4j
public class JStack {

    private static synchronized void sync () throws InterruptedException {
        log.info("sync方法获取锁, 线程名：" + Thread.currentThread().getName());
        while (true) {}
    }

    public static void deadLoop() {
        while (true) {
            System.out.println(new Date());
        }
    }

    /**
     * 查看线程阻塞进入等待区 java.lang.Thread.State: BLOCKED (on object monitor)
     * 此时看到一条线程locked <地址> 目标，另外一条线程在waiting to lock <地址> 目标
     */
    public static void threadWaitting() {
        new Thread(() -> {
            try {
                JStack.sync();
            } catch (InterruptedException e) {
                log.error("", e);
            }
        }).start();
        log.info("第一条线程在运行");

        new Thread(() -> {
            try {
                JStack.sync();
            } catch (InterruptedException e) {
                log.error("", e);
            }
        }).start();
        log.info("第二条线程在运行");
    }

    /**
     * https://blog.csdn.net/zxh87/article/details/52137335
     * Reference Handler线程一直处于waitting状态
     */
    public static void waitOn() {
        new Thread(() -> {
            log.info("waitOn方法，线程名" + Thread.currentThread().getName());
            while (true) {}
        }).start();
        log.info("第一条线程在运行");
    }

    /**
     * 线程死锁
     */
    public static void deadLock() {
        Thread t1 = new Thread(new DeadLockclass(true));//建立一个线程
        Thread t2 = new Thread(new DeadLockclass(false));//建立另一个线程
        t1.start();//启动一个线程
        t2.start();//启动另一个线程
    }

    static class DeadLockclass implements Runnable {
        public boolean falg;// 控制线程
        DeadLockclass(boolean falg) {
            this.falg = falg;
        }
        public void run() {
            /**
             * 如果falg的值为true则调用t1线程
             */
            if (falg) {
                while (true) {
                    synchronized (Suo.o1) {
                        log.info("o1 " + Thread.currentThread().getName());
                        synchronized (Suo.o2) {
                            log.info("o2 " + Thread.currentThread().getName());
                        }
                    }
                }
            }
            /**
             * 如果falg的值为false则调用t2线程
             */
            else {
                while (true) {
                    synchronized (Suo.o2) {
                        log.info("o2 " + Thread.currentThread().getName());
                        synchronized (Suo.o1) {
                            log.info("o1 " + Thread.currentThread().getName());
                        }
                    }
                }
            }
        }
    }

    static class Suo {
        static Object o1 = new Object();
        static Object o2 = new Object();
    }
}
